Tip Corner - Using Function

LB Native Function and Bill Jenning's Custom Function

© 2004, Brad Moore

author contact:

http://www.freewebz.com/lb-connection

Home

Tip Corner: Using

Game Programming

Round Buttons

Rotating Objects

LBW: Book Marks

Slide Puzzle

Speech DLL

Addresses

Beginners Programming

Newsletter help

Index


Liberty Basic Native USING Function

Liberty Basic, as is the case with most programming languages, has a function for formatting numeric output. In the case of Liberty Basic, it is the USING function.

You may be wondering why in the world anyone would want to format numeric information, but a little thought on the subject will reveal many, many advantages to controlling how a number is displayed. Here are just a few of the benefits and things you can do with this kind of control:

Liberty Basic's USING function can do all that and more. With the new automatic rounding of fractional values, a feature added with the release of version 3 to make Liberty Basic's USNIG function more consistent with other Basic's USING functions, it can easily fix a non-whole number to a specific number of decimal places.

The help file explains the use of the function very well, and offers several examples:


USING(templateString, numericExpression)

Description:

This function formats numericExpression as a string using templateString.  The rules for the format are similar to those in Microsoft BASIC's PRINT USING statement,  but since using( ) is a function, it can be used as part of a larger BASIC expression instead of being useful only for output directly.  The template string may consist of the character "#" to indicate placement for numerals, and a single dot "." to indicate placement for the decimal point.  The template string must be contained within double quote marks.  A template string would look similar to this:

amount$ = using("######.##", 1234.56)

As part of a larger expression:

notice "Your total is $" + using("####.##", 1234.5)


A template string may be expressed as a string variable:

template$ = "######.##"
amount$ = using(template$, 1234.56)


Using() may be used in conjunction with 'print'.  The following two examples will produce the same result:

amount$ = using("######.##", 123456.78)
print amount$

print using("######.##", 123456.78)

I have put together a quick and dirty little demo program that shows the power of USING to quickly and easily align a column of data around the decimal point, and round the decimal values up to a desired precision level. This demo simply loads an array of numeric variables with some randomly generated numbers. Here is the code, followed by a sample run from the program:


dim nums(10)

for x = 1 to 10
   nums(x) = rnd(0)*1111 + 10
next x

Print "Raw Data Dump -------------------"
for x = 1 to 10
   print nums(x)
next x

Print
Print "Formatted Data, 2 decimal places, aligned"
for x = 1 to 10
   print using("######.##", nums(x))
next x


Raw Data Dump -------------------
764.587608
56.9541133
1065.29224
891.117859
291.831813
908.882396
202.078629
233.821023
674.395809
122.95464

Formatted Data, 2 decimal places, aligned
   764.59
    56.95
  1065.29
   891.12
   291.83
   908.88
   202.08
   233.82
   674.40
   122.95

With all the really cool stuff that you can do with the using function, you would think that there was no room for improvement, but there seem to be a few additional things people wish they could do with the function. One of the most popular requests is to have additional characters available for definition in the "templateString". One of the most notable characters that is missing is the comma to define the hundreds, thousands, millions and so on. Another popular request is support for the various forms of money notation such as the Euro, Pound and Cent. I know that Carl has heard the request, but the priority for the enhancement has not yet made it to the top of the pile.

In the mean time, to address the needs of these programmers with more advanced needs in their common USING function, Bill Jennings (of LB Newsletter Index and Table of Contents fame) created a custom using function that is spectacular. It has not had a lot of changes since it was introduced about two years ago, and it was included (but only briefly noted) in the December 2002 issue of the newsletter. I decided to request Bill's permission to include it in the Tip Corner this month for several reasons, in spite of the fact it has been published before. First, it dovetails very nicely with the subject at hand, chiefly the Liberty Basic USING function, and second, although it is included in the 12/02 issue of the newsletter, you must download the entire archive to get the function - this time around I will include it in-line so that it can be viewed online. I really appreciate Bills contribution in the form of this function.

Brad Moore



'   usingDemo.bas  --  Bill Jennings, April 2002
'       Format a number with non-numerics

    fmat$="£µ§®$ ##,###,###,###,###,###,###.## ¢"

       'numbers to be formatted:
    DATA 22222222222222229999  'large whole number
    DATA -12345678912.4567     'typical rounding
    DATA -123456789123.4567    'minus sign spaced over
    DATA 1199.999999999999
    DATA 1.4555599999
    DATA -1234567891234.555999999
    for num=1 to 6
      READ n
        'subroutine checks number:
    gosub [checkNumber]
        'first function rounds number:
    roun$=Rounded$(n,dp,lp)
        'second function imposes format:
    formatNum$=fmatNum$(fmat$,roun$)

      print num;"  ";formatNum$
    next num
  END
'-------------------------------------------
[checkNumber]
    dp=0   'find decimal places (dp) & leading places (lp)
    d=instr(fmat$,".")  'check for decimal in format
    if d then
      for j=d+1 to len(fmat$)
        if mid$(fmat$,j,1)="#" then dp=dp+1
      next j
    else
      d=len(fmat$)
    end if
    for j=1 to d
      if mid$(fmat$,j,1)="#" then lp=lp+1
    next j

        'see if integer portion is too large for format:
    nLen=len(str$(int(n)))
    if nLen>lp then_
      notice "Notice:"+chr$(13)+"Format "+fmat$+" is"+_
      chr$(13)+"inadequate for "+str$(n) : stop
  RETURN
'----------------------------------
Function fmatNum$(fmat$,roun$)
    DIM c$(len(fmat$))
    for j=1 to len(fmat$)
      c$(j)=mid$(fmat$,j,1)
    next j

    DIM d$(len(roun$))
    for j=1 to len(roun$)
      d$(j)=mid$(roun$,j,1)
    next j

      'Find commas permissable in integer:
    a$=trim$(roun$)  'remove minus sign if present
    if left$(a$,1)="-" then a$=mid$(a$,2)
    p=instr(a$,".")-1  'start from left of decimal point,
    if p<1 then p=len(a$)  'or end of string
    comPermis=int((p+2)/3)-1

       'swap characters going backwards:
    fmatNum$="" : n=len(roun$)+1
    for j=len(fmat$) to 1 step-1
      SELECT CASE c$(j)
        CASE "."  'decimal point
          n=n-1
          fmatNum$="."+fmatNum$
        CASE "#"  'digit or space or minus
          n=n-1
          if n<1 then  'add spaces in front
            fmatNum$=" "+fmatNum$
          else
            fmatNum$=d$(n)+fmatNum$
          end if
        CASE ","  'comma delimiter
          nCom=nCom+1
          if nCom<=comPermis then
            fmatNum$=","+fmatNum$
          else
            fmatNum$=" "+fmatNum$
          end if
        CASE else
          fmatNum$=c$(j)+fmatNum$
      END SELECT
    next j
  End Function
'-------------------------------------
Function Rounded$(n,dp,lp)
    'IN: n
    'OUT: Rounded$
    '*** Specify dp (decimal places)
    '        and lp (leading places)
    xp=1   ' Get exact value of 10^dp
           ' to avoid exponent operation.
    for j=1 to dp : xp=xp*10 : next j

    if n=0 then a=0 else a=int(n*xp+n/abs(n)/2)
    if n<0 then a=abs(a) : sign$="-"
    a$=str$(a)
    int$=sign$+left$(a$,len(a$)-dp)
    if int$="" then int$="0"
    while len(int$)<lp : int$=" "+int$ : wend
    d$="00000000000000000000"
    d$=d$+d$+d$  'long enough!
    dec$=right$(d$+a$,dp)
    dot$="." : if dp=0 then dot$=""
    Rounded$=int$+dot$+dec$
  End Function

   


Home

Tip Corner: Using

Game Programming

Round Buttons

Rotating Objects

LBW: Book Marks

Slide Puzzle

Speech DLL

Addresses

Beginners Programming

Newsletter help

Index